/**
 *
 */
package coms6111.astbbw.dataminer;


import java.io.*;
import java.util.ArrayList;

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;

/**
 * @author Ben Warfield and Ashish Tomar
 *
 */
public class Miner {
	static {
		BasicConfigurator.configure();
		Logger.getRootLogger().setLevel(org.apache.log4j.Level.ERROR);
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Logger l = Logger.getLogger(Miner.class);
		DataMine mine = null;
		if (args[0].endsWith(".txt")) {
			l.info("Restoring dataset from " + args[0]);
			File dump = new File(args[0]);
			try {
				mine = GlimpseBitIndexed.unDump(dump);
			} catch (FileNotFoundException e) {
				l.fatal("Can't find file to restore from",e);
				System.exit(1);
			} catch (IOException e) {
				l.fatal("Error undumping file",e);
				System.exit(1);
			}
			l.info("Restored index for " + mine.datasetName());
		} else {
			String dataset = args[0].toLowerCase();
			mine = new GlimpseBitIndexed(dataset);
			// TODO some error checking?
			l.info("Building index for dataset " + dataset);
			mine.buildIndex();
		}
		mine.findCommon(397); // or something like that
		double supportCutoff = -1;

		FileWriter fstream =null;
		BufferedWriter out;

		BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
		boolean tryargs = args.length > 1;
		do {
			System.out.print("Enter Minimum Support cutoff (0-" + mine.getMaxSupport() +"): ");
			try {
				// FIXME should have an abort-signal here if you want it (^D/EOF)
				String inp;
				if ( tryargs ) {
					inp = args[1];
					System.out.println(args[1]);
					tryargs = false;
				} else {
					inp =  stdin.readLine();
				}
				double tmp = Double.parseDouble(inp);
				if (tmp > mine.getMaxSupport()) {
					l.debug("Cutoff " + tmp + " is impossible");
					System.out.println("Cutoff value must be smaller than maximum value");
				} else if (tmp < 0) {
					System.out.println("Cutoff value must be non-negative.");
				} else {
					supportCutoff = tmp;
				}
			} catch (NumberFormatException e) {
				/* do nothing */;
				l.debug("unable to parse supportCutoff: repeating");
			} catch (IOException e) {
				l.fatal("Unexpected error while parsing support cutoff",e);
				System.exit(-1);
			}
		} while (supportCutoff < 0);
		l.debug("Launching a priori with cutoff of " + supportCutoff);
		DataMine.ItemSet largeSets[] = mine.aPriori(supportCutoff);
		l.debug("Got " + largeSets.length + " large itemsets");
		try{
			fstream = new FileWriter("LargeSets-list-"+args[0]+".txt");
			System.out.println("The Large ItemSets are written into - LargeSets-list-"+args[0]+".txt");
			out = new BufferedWriter(fstream);
			for (int i = 0; i < largeSets.length; i++) {
				Object a[] = {
						java.util.Arrays.deepToString( largeSets[i].getItems()),
						100*largeSets[i].getSupport() };
				l.debug(String.format("%s, %f%%", a));
				out.write(String.format("%s, %.2f", a));
				out.newLine();


			}


			out.close();
		}
		catch(IOException e){
			l.debug("Error in opening large sets containing the term output files");

		}
		// Select word and confidence cutoff
		String chosen = "";
		double minConf = -1;
		tryargs = args.length > 2;
		do {
			System.out.print("Enter word: ");
			try {
				String tmp;
				if ( tryargs ) {
					tmp = args[2];
					System.out.println(args[2]);
					tryargs = false;
				} else {
					tmp = stdin.readLine();
				}
				if (null != tmp) chosen = tmp.trim();
				if (0 <= chosen.indexOf(' ')) {
					System.out.println("Just ONE word, please!");
					chosen = "";
				}
			} catch (IOException e) {
				l.fatal(e);
				System.exit(2);
			}
		} while ( 0 == chosen.length() );
		tryargs = args.length > 3;
		do {
			System.out.print("Enter minimum confidence (0-1): ");
			try {
				// FIXME should have an abort-signal here if you want it (^D/EOF)
				String inp;
				if ( tryargs ) {
					inp = args[3];
					System.out.println(args[3]);
					tryargs = false;
				} else {
					inp = stdin.readLine();
				}
				double tmp = Double.parseDouble(inp);
				minConf = tmp;
			} catch (NumberFormatException e) {
				/* do nothing */;
				l.debug("unable to parse minConf: repeating");
			} catch (IOException e) {
				l.fatal("Unexpected error while parsing confidence cutoff",e);
				System.exit(-1);
			}
		} while (minConf < 0);

		largeSets = mine.getByMember(chosen);
		l.debug("Found " + largeSets.length + " itemsets containing " + chosen);
		try{
			
			if ( l.isDebugEnabled() ) {
				fstream = new FileWriter("LargeSets-"+args[0]+"-containing-"+chosen+"-list.txt");
				out = new BufferedWriter(fstream);
				for (int i = 0; i < largeSets.length; i++) {
					Object a[] = { java.util.Arrays.deepToString(largeSets[i].getItems()), largeSets[i].getSupport() };
					l.debug(String.format("%s, %.2f", a));
					out.write(String.format("%s, %.2f", a));
					out.newLine();


				}
				out.close();
			}

			
		}
		catch(IOException e){
			l.debug("Error in opening large sets containing the term output files");

		}


		ArrayList<DataMine.Inference> inferredRules= mine.calInference(largeSets, minConf);
		mine.printInferredRules(inferredRules);
		mine.destroy();
	}

}
